package JVM.第03篇_运行时内存篇;

import org.junit.Test;

/**
 *  stack  线程私有
 *      1 栈（stack）管运行  //内存小  线程 无垃圾回收
 *        堆(heap)管存储    //内存大  有垃圾回收
 *      2 栈保存的：
 *        8种基本类型的变量  +对象的引用变量   +实例方法都是在函数的栈
 *      3  java.lang.StackOverflowError  //Error 错误不是异常
 *          栈内存有限  递归死循环内存撑爆了          堆    溢出    错误
 *
 * 栈也叫栈内存，主管Java程序的运行，是在线程创建时创建，
 * 它的生命期是跟随线程的生命期，线程结束栈内存也就释放，
 * 对于栈来说不存在垃圾回收问题，只要线程--结束该栈就Over，
 * 生命周期和线程一致，是线程私有的。
 *
 * "8种基本类型的变量+对象的引用变量"+实例方法都是在函数的栈内存中分配。
 *
 *
 * 设置栈空间大小
 * -Xss  等价于-XX:ThreadStackSize //单个线程栈的大小  一般默认为513k-1024k
 *      如     -Xss1024k
 *      JDK5前  默认 256k
 *      JDK5后  默认 1024k
 *
 * 设置的栈空间值过大，会导致系统可以用于创建线程的数量减少。
 * 一般一个进程中通常有3000-5000个线程。
 */
public class B_虚拟机栈 {
    public static void main(String[] args) {
        StackText();
    }

    public  void changeValue1(int  age){age=30;}//传的是复制品
    public void changeValue2(Stack1 stack1){
        stack1.setName("xxx");
    }//传的是地址
    public void changeValue3(String str){
        str="xxx";
        //String传的也是地址   但是String是不可变的
        // 修改它等同于 自动找新的空间地址改变
    }

    private static void StackText() {
        B_虚拟机栈 jvm=new B_虚拟机栈();

        int age=20;//基本类型  穿得是复印件  值
        jvm.changeValue1(age);
        System.out.println(age);//20

        Stack1 person =new Stack1("abc");
        jvm.changeValue2(person);//引用类型  传的是地址
        System.out.println(person.getName());//xxx

        String str="abc";//String  特殊 传的是地址  但是如果穿的值修改了  修改的不是源地址的值
        jvm.changeValue3(str);//他传的str会重新 指定一个新地址  原本的str还是原来的str
        System.out.println(str);//abc   他保存在字符串常量池中
    }//堆得分层

    @Test
    public void OOM(){
        stackOverflowError(0);
    }
    private static void stackOverflowError(int i) {
        System.out.println(i++);
        stackOverflowError(i);//递归
        //java.lang.StackOverflowError//Error 错误不是异常
    }//栈溢出错误   栈满了


}
class Stack1{
    public String a=null;

    public Stack1(String abc) {
        this.a=abc;
    }
    public Stack1() {

//        空参默认有 super();
    }

    public void setName(String xxx) {
        this.a=xxx;
    }

    public String getName() {
        return this.a;
    }

}
